/**
 * Copyright 2010 Creative Works, Inc.
 * Creative Works licenses this file to you under the Apache License, version
 * 2.0 (the "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *    http://www.apache.org/licenses/LICENSE-2.0
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 * implied.  See the License for the specific language governing
 * permissions and limitations under the License.
 */
package org.sendvox.freswitch.util;

import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;

public enum Arguments {

	INSTANCE;

	private List<Object> argsList = new ArrayList<Object>();

	public Arguments validate(Object... args) {
		if (args != null) {
			if (argsList != null)
				argsList.clear();
			for (Object object : args) {
				argsList.add(object);
			}
		} else {
			throw new NullPointerException("Argument can't be null");
		}
		return this;
	}

	/**
	 * If <code>aText</code> does not satisfy {@link Util#textHasContent}, then
	 * throw an <code>IllegalArgumentException</code>.
	 * 
	 * <P>
	 * Most text used in an application is meaningful only if it has visible
	 * content.
	 */
	public Arguments isNotEmpty() throws IllegalArgumentException {
		for (Object param : argsList) {
			if (!Util.textHasContent(param.toString())) {
				throw new IllegalArgumentException(
						"Argument has no visible content");
			}
		}
		return this;
	}

	/**
	 * If <code>aObject</code> is null, then throw a
	 * <code>NullPointerException</code>.
	 */
	public Arguments isNotNull() throws NullPointerException {
		for (Object param : argsList) {
			if (param == null) {
				throw new NullPointerException("Argument can't be null");
			}
		}
		return this;
	}

	/**
	 * If {@link Util#isInRange} returns <code>false</code>, then throw an
	 * <code>IllegalArgumentException</code>.
	 * 
	 * @param aLow
	 *            is less than or equal to <code>aHigh</code>.
	 */
	public Arguments isInRange(int aLow, int aHigh) {
		for (Object param : argsList) {
			if (param != null) {
				if (param instanceof Integer) {
					Integer aNumber = new Integer(param.toString());
					if (!Util.isInRange(aNumber, aLow, aHigh)) {
						throw new IllegalArgumentException(aNumber
								+ " not in range " + aLow + ".." + aHigh);
					}
				}
			}
		}
		return this;
	}

	/**
	 * If <tt>aNumber</tt> is less than <tt>1</tt>, then throw an
	 * <tt>IllegalArgumentException</tt>.
	 */
	public Arguments isPositive() {
		for (Object param : argsList) {
			if (param != null) {
				if (param instanceof Integer) {
					Integer aNumber = new Integer(param.toString());
					if (aNumber < 1) {
						throw new IllegalArgumentException(aNumber
								+ " is less than 1");
					}
				}
			}
		}
		return this;
	}

	/**
	 * If {@link Util#matches} returns <tt>false</tt>, then throw an
	 * <code>IllegalArgumentException</code>.
	 */
	public Arguments matches(Pattern aPattern) {
		for (Object param : argsList) {
			if (!Util.matches(aPattern, param.toString())) {
				throw new IllegalArgumentException("Text "
						+ Util.quote(param.toString()) + " does not match '"
						+ aPattern.pattern() + "'");
			}
		}
		return this;
	}

	/**
	 * If <code>aObject</code> is null, then throw a
	 * <code>NullPointerException</code>.
	 */
	public Arguments isValidHostAddress() throws UnknownHostException {
		String validIPAddressRegex = "^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$";
		String validHostnameRegex = "^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\\-]*[a-zA-Z0-9])\\.)*([A-Za-z]|[A-Za-z][A-Za-z0-9\\-]*[A-Za-z0-9])$";

		for (Object param : argsList) {
			String hostName = param.toString();

			Pattern ipPattern = Pattern.compile(validIPAddressRegex);
			Pattern hostNamePattern = Pattern.compile(validHostnameRegex);

			if (!ipPattern.matcher(hostName).matches()
					&& !hostNamePattern.matcher(hostName).matches()) {
				throw new UnknownHostException("The Internet address ["
						+ hostName + "] is not valid");
			}

		}
		return this;
	}

}
